package com.guosen.zebra.framework.starter.alarm.internal;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.guosen.zebra.framework.basic.http.OKHttpClientUtil;
import com.guosen.zebra.framework.starter.alarm.exception.AlarmException;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;

@Slf4j
public class AlarmHttpClient {

    private AlarmHttpClient() {}

    /**
     * JSON类型
     */
    public static final MediaType JSON_TYPE = MediaType.parse("application/json; charset=utf-8");

    /**
     * http协议客户端
     */
    private static final OkHttpClient HTTP_CLIENT = OKHttpClientUtil.getHttpClient();

    /**
     * https客户端，忽略证书
     */
    private static final OkHttpClient UNSAFE_HTTPS_CLIENT = OKHttpClientUtil.getUnsafeHttpsClient();

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    public static Object postAlarmEvent(String url, Map<String, String> headers, Object parameters)
            throws AlarmException {
        String jsonParam = object2String(parameters);
        Request request = buildRequest(url, headers, jsonParam);
        return doInvoke(request, url);
    }

    private static String object2String(Object o) {
        try {
            return OBJECT_MAPPER.writeValueAsString(o);
        } catch (JsonProcessingException e) {
            throw new AlarmException("告警事件请求参数处理异常！", e);
        }
    }

    private static Request buildRequest(String url, Map<String, String> headers, String jsonParam) {
        try {
            RequestBody body = RequestBody.create(JSON_TYPE, jsonParam);
            Request.Builder builder = new Request.Builder().url(url).post(body);
            setHeaders(headers, builder);
            return builder.build();
        } catch (Exception e) {
            log.error("Failed to build request, url: {}, error message : {}", url, e.getMessage(), e);
            throw new AlarmException("请求创建异常！", e);
        }
    }

    private static void setHeaders(Map<String, String> headers, Request.Builder builder) {
        for (Map.Entry<String, String> header : headers.entrySet()) {
            builder.header(header.getKey(), header.getValue());
        }
    }

    private static String doInvoke(Request request, String url) throws AlarmException {
        try (Response response = getHttpClient(url).newCall(request).execute();
             ResponseBody responseBody = response.body()){
            if (responseBody != null) {
                return responseBody.string();
            }
        } catch (Exception e) {
            log.error("Failed to invoke {}, error message : {}", url, e.getMessage(), e);
            throw new AlarmException("500", e.getMessage());
        }
        return null;
    }

    private static OkHttpClient getHttpClient(String url) {
        boolean isHttps = StringUtils.startsWithIgnoreCase(url, "https");
        return isHttps ? UNSAFE_HTTPS_CLIENT : HTTP_CLIENT;
    }
}
